/*
 * ZENworks Notification Icon
 * Copyright (C) Author: Gangadhar Nagesh Metla (Novell, Inc.)
 * nmetla74@gmail.com 
 * Version 1.0
 * 1/3/2009
 * Filename ZProgressDialog.java
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package com.novell.zenworks.agent.zicon.progress;

import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;

import com.novell.zenworks.agent.common.ICommonUIEnums.MB_ICON;
import com.novell.zenworks.agent.common.ICommonUIEnums.MB_RESPONSE;
import com.novell.zenworks.agent.common.ICommonUIEnums.MB_TYPE;
import com.novell.zenworks.agent.zbrowser.MessageBoxLauncher;
import com.novell.zenworks.agent.zicon.ZTrayIcon;
import com.novell.zenworks.zicon.common.LogUtil;
import com.novell.zenworks.zicon.common.progress.ITaskSetProgress;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.util.Timer;
    
public class ZProgressDialog extends JFrame 
{
    private static final long serialVersionUID = 1L;
    private static ZProgressDialog progressDialog = null;
    private static Object lock = new Object();
    private JPanel dynamicPanel = null;
    protected boolean cleaned = false;

    public ZProgressDialog() throws Exception
    {
        setSize(400,240);
        setPreferredSize(new Dimension(400,200));
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        initialize();
    }//ZProgressDialog
 
	public void initialize() throws Exception
	{
		if(!System.getProperty("os.name").toLowerCase().contains("mac"))
        {
            String titleImage =  ZTrayIcon.getImagesPath() + File.separator + "Application.png";
            ImageIcon titleIcon = new ImageIcon(titleImage);
            this.setIconImage(titleIcon.getImage());
        }
		
		
		setTitle(ZTrayIcon.rm.getString("StatusDlgTitle"));
		
		JScrollPane scrollPane = new JScrollPane();
		
		dynamicPanel = new JPanel();
        dynamicPanel.setAutoscrolls(true);
        dynamicPanel.setLayout(new BoxLayout(dynamicPanel, BoxLayout.Y_AXIS));
        
		scrollPane.setBorder(new EmptyBorder(5, 0, 0, 0));
		scrollPane.setWheelScrollingEnabled(true);
		scrollPane.setAutoscrolls(true);
		scrollPane.setViewportView(dynamicPanel);		
		getContentPane().add(scrollPane, BorderLayout.CENTER);
		addWindowListener();
		addKeyListener();
		pack();
		setVisible(false); //Show only when it makes sense.
	}
	
	private void addKeyListener()
    {
        this.addKeyListener(new KeyListener(){

            public void keyPressed(KeyEvent event)
            {
                if(event.getKeyCode() == KeyEvent.VK_ENTER)
                {
                        try
                        {
                            removeSelectedPanel();
                        } catch (Exception e)
                        {
                            try
                            {
                                LogUtil.LogException(e.getMessage(), e);
                                if(e.getLocalizedMessage() != null)
                                {
                                    MessageBoxLauncher.ShowMessageBoxHandler(e.getLocalizedMessage(), ZTrayIcon.rm.getString("PropDlgTitle") , MB_TYPE.MBT_OK, MB_ICON.MBI_ERROR, 30, false, MB_RESPONSE.MBR_OK);
                                }
                                else
                                {
                                    MessageBoxLauncher.ShowMessageBoxHandler(ZTrayIcon.rm.getString("RemotingError"), ZTrayIcon.rm.getString("PropDlgTitle") , MB_TYPE.MBT_OK, MB_ICON.MBI_ERROR, 30, false, MB_RESPONSE.MBR_OK);
                                }
                            } catch (Exception e1)
                            {
                                LogUtil.LogException(e.getMessage(), e1);
                            }
                        }
                }            
            }

            public void keyReleased(KeyEvent e)
            {
                // TODO Auto-generated method stub
                
            }

            public void keyTyped(KeyEvent e)
            {
                // TODO Auto-generated method stub
                
            }});
        
    }

    private void addWindowListener()
    {
	    this.addWindowListener(new WindowListener(){

            public void windowActivated(WindowEvent e)
            {
                // TODO Auto-generated method stub
                
            }

            public void windowClosed(WindowEvent e)
            {
                // TODO Auto-generated method stub
                
            }

            public void windowClosing(WindowEvent e)
            {
                if(dynamicPanel.getComponentCount() < 1)
                {
                    progressDialog.dispose();
                    progressDialog = null;
                }
                
                //Just make it invisible. Progress Dialog will be cleaned up when there are ZERO items.
                if(progressDialog != null)
                    progressDialog.setVisible(false);            
            }

            public void windowDeactivated(WindowEvent e)
            {
                // TODO Auto-generated method stub
                
            }

            public void windowDeiconified(WindowEvent e)
            {
                // TODO Auto-generated method stub
                
            }

            public void windowIconified(WindowEvent e)
            {
                // TODO Auto-generated method stub
                
            }

            public void windowOpened(WindowEvent e)
            {
                // TODO Auto-generated method stub
                
            }});
        
    }

    public void addProgressPanel(ITaskSetProgress progress)
	{
	    try
        {
	        boolean exists = false;
	        Component[] comps = dynamicPanel.getComponents();
	        for(int i=0; i < comps.length; i++)
	        {
	            if(comps[i] instanceof ZProgressPanel && comps[i].getName().equals(progress.getUID()))
	            {
	                synchronized(lock)
	                {
	                    ((ZProgressPanel)comps[i]).update(progress);
	                    exists = true;
	                }
	            }
	        }

	        if(!exists)
	        {
	            ZProgressPanel progressPanel = new ZProgressPanel(progress);
	            dynamicPanel.add(progressPanel);	            
	        }
	        
	        validate();
        } catch (Exception e)
        {
            try
            {
                LogUtil.LogException(e.getMessage(), e);
                if(e.getLocalizedMessage() != null)
                {
                    MessageBoxLauncher.ShowMessageBoxHandler(e.getLocalizedMessage(), ZTrayIcon.rm.getString("PropDlgTitle") , MB_TYPE.MBT_OK, MB_ICON.MBI_ERROR, 30, false, MB_RESPONSE.MBR_OK);
                }
                else
                {
                    MessageBoxLauncher.ShowMessageBoxHandler(ZTrayIcon.rm.getString("RemotingError"), ZTrayIcon.rm.getString("PropDlgTitle") , MB_TYPE.MBT_OK, MB_ICON.MBI_ERROR, 30, false, MB_RESPONSE.MBR_OK);
                }
            } catch (Exception e1)
            {
                LogUtil.LogException(e.getMessage(), e1);
            }
        }       
	}

    private void refreshDialog()
    {
        this.pack();
        this.requestFocusInWindow();
        this.repaint(0);        
    }
    
    public void unIconify()
    {
        this.toFront();    
    }

    public static ZProgressDialog getInstance() throws Exception
    {
        if(progressDialog == null)
        {
            synchronized(lock)
            {
                if(progressDialog == null)
                    progressDialog = new ZProgressDialog();                
            }            
        }
        else
        {
            progressDialog.unIconify();
        }
        
        return progressDialog;
    }

    public int getNumberOfPanels()
    {
        return dynamicPanel.getComponentCount();
    }
    
    public synchronized void removePanel(String uid, boolean disposeOnLast)
    {
        Component[] comps = dynamicPanel.getComponents();
        for(int i=0; i < comps.length; i++)
        {
            if(comps[i].getName().equals(uid))
            {
                dynamicPanel.remove(comps[i]);
                int numPanels = getNumberOfPanels();
                if(i < numPanels)
                    ((ZProgressPanel)comps[i+1]).setSelected(true);
                else
                    ((ZProgressPanel)comps[0]).setSelected(true);
                break;
            }
        }
        validate();
       
        //dispose the dialog if zero progress elements.
        if(getNumberOfPanels() < 1 && disposeOnLast)
        {
            progressDialog.dispose();
            progressDialog = null;
        }
    }
    
    private synchronized void removeSelectedPanel()
    {
        Component[] comps = dynamicPanel.getComponents();
        for(int i=0; i < comps.length; i++)
        {
            if(comps[i] instanceof ZProgressPanel && ((ZProgressPanel)comps[i]).isSelected())
            {
                dynamicPanel.remove(comps[i]);
                int numPanels = getNumberOfPanels();
                if(i < numPanels)
                    ((ZProgressPanel)comps[i+1]).setSelected(true);
                else
                    ((ZProgressPanel)comps[0]).setSelected(true);
                
                break;
            }
        }
        validate();
       
        //dispose the dialog if zero progress elements.
        if(getNumberOfPanels() < 1)
        {
            progressDialog.dispose();
            progressDialog = null;
        }
    }

    public void postpone(String uid) throws Exception
    {
        Component[] comps = dynamicPanel.getComponents();
        for(int i=0; i < comps.length; i++)
        {
            if(comps[i] instanceof ZProgressPanel && comps[i].getName().equals(uid))
            {
                ITaskSetProgress progress = ((ZProgressPanel)comps[i]).progress;
                progress.postpone();                
            }
        }        
    }

    public void unSelectAll()
    {
        Component[] comps = dynamicPanel.getComponents();
        for(int i=0; i < comps.length; i++)
        {
            if(comps[i] instanceof ZProgressPanel)
            {
                ((ZProgressPanel)comps[i]).setSelected(false);              
            }
        }
                
    }

    public void selectPanel(int i)
    {
        Component panel = dynamicPanel.getComponent(i);
        if(panel instanceof ZProgressPanel)
            ((ZProgressPanel)panel).setSelected(true);        
    }

	public static void nullify() 
	{
	    progressDialog = null;	
	}
}
